package kaa.archivator;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;


public class FileInfo implements IFileMetaData {
    private long size;
    private Path filepath;
    private byte[] file = null;
    private int firstFolderNameCount;

    public FileInfo() {
    }

    public FileInfo(Path filename, Path FirstFolPath, boolean isDirectory) {
        firstFolderNameCount = FirstFolPath.getNameCount();
        setFilepath(filename);
        try {
            if (isDirectory) {
                setSize(-1);
            } else {
                setSize(Files.readAttributes(filename, BasicFileAttributes.class).size());
                setFile(Files.readAllBytes(filename));
            }
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    public byte[] getByteMetaInfo() {
        int metasize = 4 + 8 + 4 + filepath.toString().length();
        ByteBuffer bb = ByteBuffer.allocate(metasize);
        bb.putInt(metasize - 4);
        bb.putLong(getSize());
        // zipPath - to store less and restore easier
        Path zipPath = filepath.subpath(firstFolderNameCount - 1, filepath.getNameCount());
        bb.putInt(zipPath.toString().length());
        bb.put(zipPath.toString().getBytes());
        bb.flip();
        return bb.array();
    }

    public void setMetaInfo(byte[] info) {
        ByteBuffer bb = ByteBuffer.wrap(info);
        long size = bb.getLong();
        int stringLen = bb.getInt();
        byte[] a = new byte[stringLen];
        bb.get(a);
        bb.flip();
        String filename = new String(a);
        setSize(size);
        Path file = FileSystems.getDefault().getPath(filename);
        if (size != -1) {
            setFilepath(file);
        } else {
            filepath = file;
        }
    }

    public byte[] getByteFullInfo() {
        ByteBuffer meta = ByteBuffer.wrap(getByteMetaInfo());
        if (file != null) {
            ByteBuffer full = ByteBuffer.allocate(meta.capacity() + 4 + getFile().length);
            full.put(meta);
            full.putInt(getFile().length);
            full.put(getFile());
            full.flip();
            return full.array();
        } else {
            return meta.array();
        }
    }


    public long getSize() {
        return size;
    }

    public void setSize(long size) {
        this.size = size;
    }

    public Path getFilepath() {
        return filepath;
    }

    public void setFilepath(Path filepath) {
        this.filepath = filepath;
    }

    public byte[] getFile() {
        return file;
    }

    public void setFile(byte[] file) {
        this.file = file;
    }


}
